﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.ObjectModel;

namespace BE.Web.Betfair.Interface.Entities
{
    /// <summary>
    /// A bet event on which can be betted.
    /// </summary>
    [DebuggerDisplay("{Id} - {Name}")]
    public sealed class BetEvent
    {
        /// <summary>
        /// The Id of the vent
        /// </summary>
        public int Id { get; private set; }

        /// <summary>
        /// Gets or sets the sub events.
        /// </summary>
        /// <value>The sub events.</value>
        public ObservableCollection<BetEvent> SubEvents { get; private set; }

        /// <summary>
        /// Gets or sets the associated markets.
        /// </summary>
        /// <value>The associated markets.</value>
        public List<BetMarketSummary> AssociatedMarkets {get; private set;}

        /// <summary>
        /// Name of the EVent
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Gives a value when the event will start
        /// </summary>
        public DateTime StartTime { get; private set; }

        /// <summary>
        /// The Order
        /// </summary>
        public int OrderIndex { get; private set; }


        /// <summary>
        /// THe Type of the event
        /// </summary>
        public BetEventType EventType { get; private set; }


        /// <summary>
        /// Gets or sets the time zone.
        /// </summary>
        /// <value>The time zone.</value>
        public string TimeZone { get; private set; }

        /// <summary>
        /// Code Contract invariants
        /// </summary>
        [ContractInvariantMethod]
        void ObjectInvariant()
        {
            Contract.Invariant(this.Name != null);
            Contract.Invariant(this.EventType != null);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BetEvent"/> class.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="name">The name.</param>
        /// <param name="eventType">Type of the event.</param>
        /// <param name="start">The start.</param>
        /// <param name="orderIndex">Index of the order.</param>
        /// <param name="timezone">The timezone.</param>
        /// <param name="marketIds">The ids of the associated marketsmarketName</param>
        public BetEvent(int id, string name, BetEventType eventType,DateTime start,int orderIndex,string timezone,
            IEnumerable<BetMarketSummary> marketIds)
        {
            #region conditions
            Contract.Requires<ArgumentException>(name != null);
            Contract.Requires<ArgumentException>(eventType != null);
            
            Contract.Ensures(this.Name != null);
            Contract.Ensures(this.EventType != null);
            #endregion

            this.Id = id;
            this.Name = name;
            this.EventType = eventType;
            this.StartTime = start;
            this.OrderIndex = orderIndex;
            this.TimeZone = timezone;
            this.SubEvents = new ObservableCollection<BetEvent>();
            if (marketIds != null)
            {
                List<BetMarketSummary> marketList = new List<BetMarketSummary>();
                this.AssociatedMarkets = new List<BetMarketSummary>(marketList);
            }
            else
            {
                this.AssociatedMarkets = new List<BetMarketSummary>(new List<BetMarketSummary>());
            }
        }

        #region overrides

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj)
        {
            bool equal = false;

            if (obj != null && obj is BetEvent)
            {
                if (Object.ReferenceEquals(this, obj))
                {
                    equal = true;
                }
                else
                {
                    equal = ((BetEvent)obj).Id == this.Id;
                }
            }

            return equal;
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            return this.Id.GetHashCode();
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return this.Name;
        }
        #endregion
    }
        
}

